From 4f8e52440b1d47b00bb0e9ae1e63307a61c75e25 Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Wed, 18 Jan 2023 09:58:48 -0700 Subject: [PATCH] Enable the gpx reader to use the declared namespace prefixes for recognized namespace URIs. (#990) * use the declared ns prefixes in the gpx reader. * remap other used uris, even though we have never seen a different prefix used with them. delete GARMIN_RTEPT_EXT, which was never used and appears to have never existed. --- gpx.cc | 25 +- gpx.h | 2 +- reference/track/garminconnect.csv | 69 +++ reference/track/garminconnect.gpx | 699 ++++++++++++++++++++++++++++++ testo.d/gpx.test | 6 +- 5 files changed, 797 insertions(+), 4 deletions(-) create mode 100644 reference/track/garminconnect.csv create mode 100644 reference/track/garminconnect.gpx diff --git a/gpx.cc b/gpx.cc index 19c626b35..e0824f56c 100644 --- a/gpx.cc +++ b/gpx.cc @@ -976,6 +976,27 @@ GpxFormat::wr_deinit() mkshort_del_handle(&mkshort_handle); } +QString +GpxFormat::qualifiedName() const +{ + /* The prefixes used in our hash table may not match those used in the input + * file. So we map from the namespaceUris to the prefixes used in our + * hash table. + */ + static const QHash tag_ns_prefixes = { + {"http://www.garmin.com/xmlschemas/GpxExtensions/v3", "gpxx"}, + {"http://www.garmin.com/xmlschemas/TrackPointExtension/v1", "gpxtpx"}, + {"http://www.groundspeak.com/cache/1/0", "groundspeak"}, + {"http://humminbird.com", "h"} + }; + + if (auto uri = reader->namespaceUri().toString(); tag_ns_prefixes.contains(uri)) { + return QStringLiteral("%1:%2").arg(tag_ns_prefixes.value(uri)).arg(reader->name()); + } else { + return reader->qualifiedName().toString(); + } +} + void GpxFormat::read() { @@ -985,13 +1006,13 @@ GpxFormat::read() switch (reader->tokenType()) { case QXmlStreamReader::StartElement: current_tag.append(QLatin1Char('/')); - current_tag.append(reader->qualifiedName()); + current_tag.append(qualifiedName()); gpx_start(reader->qualifiedName(), reader->attributes()); break; case QXmlStreamReader::EndElement: gpx_end(reader->qualifiedName()); - current_tag.chop(reader->qualifiedName().length() + 1); + current_tag.chop(qualifiedName().length() + 1); cdatastr.clear(); break; diff --git a/gpx.h b/gpx.h index 7248758f8..f02da3b21 100644 --- a/gpx.h +++ b/gpx.h @@ -194,6 +194,7 @@ private: void gpx_start(QStringView el, const QXmlStreamAttributes& attr); void gpx_end(QStringView unused); void gpx_cdata(QStringView s); + QString qualifiedName() const; void write_attributes(const QXmlStreamAttributes& attributes) const; void fprint_xml_chain(XmlTag* tag, const Waypoint* wpt) const; void write_gpx_url(const UrlList& urls) const; @@ -309,7 +310,6 @@ private: #define GARMIN_TRK_EXT "/gpx/trk/extensions/gpxx:TrackExtension" #define GARMIN_WPT_EXT "/gpx/wpt/extensions/gpxx:WaypointExtension" #define GARMIN_TRKPT_EXT "/gpx/trk/trkseg/trkpt/extensions/gpxtpx:TrackPointExtension" -#define GARMIN_RTEPT_EXT "/gpx/rte/rtept/extensions/gpxxx:RoutePointExtension" // Maintain a fast mapping from full tag names to the struct above. const QHash hash = { diff --git a/reference/track/garminconnect.csv b/reference/track/garminconnect.csv new file mode 100644 index 000000000..12eb73b09 --- /dev/null +++ b/reference/track/garminconnect.csv @@ -0,0 +1,69 @@ +No,Latitude,Longitude,Altitude,Temperature,Heartrate,Date,Time +1,40.188950,-105.178361,1531.4,2.000,82,2023/01/16,18:02:26 +2,40.188957,-105.178339,1531.4,2.000,85,2023/01/16,18:02:27 +3,40.188963,-105.178315,1531.4,2.000,86,2023/01/16,18:02:28 +4,40.188971,-105.178263,1531.2,2.000,89,2023/01/16,18:02:32 +5,40.188971,-105.178262,1531.2,2.000,89,2023/01/16,18:02:33 +6,40.188983,-105.178206,1531.8,2.000,88,2023/01/16,18:02:44 +7,40.188998,-105.178162,1531.8,2.000,89,2023/01/16,18:02:46 +8,40.189031,-105.178122,1531.8,2.000,90,2023/01/16,18:02:48 +9,40.189094,-105.178109,1531.8,2.000,91,2023/01/16,18:02:50 +10,40.189316,-105.178108,1531.8,2.000,94,2023/01/16,18:02:55 +11,40.189363,-105.178108,1531.8,2.000,95,2023/01/16,18:02:56 +12,40.189758,-105.178102,1531.8,2.000,97,2023/01/16,18:03:04 +13,40.189978,-105.178095,1532.2,2.000,100,2023/01/16,18:03:08 +14,40.190082,-105.178094,1532.4,2.000,101,2023/01/16,18:03:10 +15,40.190133,-105.178094,1532.4,2.000,101,2023/01/16,18:03:11 +16,40.190377,-105.178097,1532.6,2.000,103,2023/01/16,18:03:16 +17,40.190776,-105.178089,1532.4,2.000,106,2023/01/16,18:03:23 +18,40.190834,-105.178090,1532.4,2.000,106,2023/01/16,18:03:24 +19,40.191182,-105.178084,1532.8,2.000,109,2023/01/16,18:03:30 +20,40.191237,-105.178084,1532.8,2.000,109,2023/01/16,18:03:31 +21,40.191689,-105.178075,1533.2,2.000,110,2023/01/16,18:03:39 +22,40.191743,-105.178076,1533.4,2.000,111,2023/01/16,18:03:40 +23,40.192095,-105.178072,1534.4,2.000,112,2023/01/16,18:03:47 +24,40.192483,-105.178072,1535.4,2.000,113,2023/01/16,18:03:55 +25,40.192534,-105.178072,1535.6,2.000,113,2023/01/16,18:03:56 +26,40.192885,-105.178070,1535.8,2.000,113,2023/01/16,18:04:03 +27,40.192936,-105.178069,1536.0,2.000,114,2023/01/16,18:04:04 +28,40.193182,-105.178068,1536.6,2.000,114,2023/01/16,18:04:09 +29,40.193478,-105.178065,1537.0,2.000,115,2023/01/16,18:04:15 +30,40.193685,-105.178062,1537.8,2.000,116,2023/01/16,18:04:19 +31,40.193785,-105.178061,1538.0,2.000,117,2023/01/16,18:04:21 +32,40.194070,-105.178063,1538.2,1.000,117,2023/01/16,18:04:27 +33,40.194211,-105.178070,1539.0,1.000,117,2023/01/16,18:04:30 +34,40.194407,-105.178069,1539.4,1.000,116,2023/01/16,18:04:34 +35,40.194740,-105.178065,1540.0,1.000,117,2023/01/16,18:04:41 +36,40.195247,-105.178051,1540.8,1.000,117,2023/01/16,18:04:51 +37,40.195558,-105.178050,1541.4,1.000,118,2023/01/16,18:04:57 +38,40.195773,-105.178047,1541.8,1.000,119,2023/01/16,18:05:01 +39,40.195996,-105.178040,1542.0,1.000,119,2023/01/16,18:05:05 +40,40.196305,-105.178035,1542.6,1.000,120,2023/01/16,18:05:11 +41,40.196452,-105.178031,1542.8,1.000,120,2023/01/16,18:05:14 +42,40.196601,-105.178033,1543.0,1.000,120,2023/01/16,18:05:17 +43,40.196808,-105.178036,1543.8,1.000,120,2023/01/16,18:05:21 +44,40.196950,-105.178046,1544.0,1.000,119,2023/01/16,18:05:24 +45,40.197042,-105.178048,1544.2,1.000,119,2023/01/16,18:05:26 +46,40.197246,-105.178035,1544.6,1.000,119,2023/01/16,18:05:30 +47,40.197483,-105.178040,1544.8,1.000,118,2023/01/16,18:05:35 +48,40.197576,-105.178042,1545.2,1.000,118,2023/01/16,18:05:37 +49,40.197770,-105.178047,1545.8,1.000,119,2023/01/16,18:05:41 +50,40.197970,-105.178047,1546.4,1.000,119,2023/01/16,18:05:45 +51,40.198120,-105.178040,1547.0,1.000,120,2023/01/16,18:05:48 +52,40.198315,-105.178041,1547.4,1.000,121,2023/01/16,18:05:52 +53,40.198365,-105.178042,1547.4,1.000,121,2023/01/16,18:05:53 +54,40.198734,-105.178037,1547.8,1.000,121,2023/01/16,18:06:00 +55,40.199171,-105.178031,1547.8,1.000,120,2023/01/16,18:06:08 +56,40.199619,-105.178020,1548.2,1.000,119,2023/01/16,18:06:16 +57,40.200012,-105.178023,1548.2,1.000,116,2023/01/16,18:06:23 +58,40.200063,-105.178024,1548.2,1.000,116,2023/01/16,18:06:24 +59,40.200495,-105.178016,1548.2,1.000,113,2023/01/16,18:06:32 +60,40.200981,-105.178015,1548.4,1.000,112,2023/01/16,18:06:41 +61,40.201536,-105.178011,1548.8,1.000,110,2023/01/16,18:06:51 +62,40.201910,-105.178013,1549.2,0.000,111,2023/01/16,18:06:58 +63,40.202125,-105.178011,1549.4,0.000,111,2023/01/16,18:07:02 +64,40.202591,-105.178010,1550.0,0.000,111,2023/01/16,18:07:11 +65,40.202744,-105.178010,1550.4,0.000,110,2023/01/16,18:07:14 +66,40.202967,-105.178011,1550.6,0.000,108,2023/01/16,18:07:19 +67,40.203058,-105.178006,1550.8,0.000,104,2023/01/16,18:07:22 +68,40.203097,-105.178007,1550.8,0.000,103,2023/01/16,18:07:24 diff --git a/reference/track/garminconnect.gpx b/reference/track/garminconnect.gpx new file mode 100644 index 000000000..0da12b4c7 --- /dev/null +++ b/reference/track/garminconnect.gpx @@ -0,0 +1,699 @@ + + + + + Garmin Connect + + + + + Boulder Cycling + cycling + + + 1531.4000244140625 + + + + 2.0 + 82 + + + + + 1531.4000244140625 + + + + 2.0 + 85 + + + + + 1531.4000244140625 + + + + 2.0 + 86 + + + + + 1531.199951171875 + + + + 2.0 + 89 + + + + + 1531.199951171875 + + + + 2.0 + 89 + + + + + 1531.800048828125 + + + + 2.0 + 88 + + + + + 1531.800048828125 + + + + 2.0 + 89 + + + + + 1531.800048828125 + + + + 2.0 + 90 + + + + + 1531.800048828125 + + + + 2.0 + 91 + + + + + 1531.800048828125 + + + + 2.0 + 94 + + + + + 1531.800048828125 + + + + 2.0 + 95 + + + + + 1531.800048828125 + + + + 2.0 + 97 + + + + + 1532.199951171875 + + + + 2.0 + 100 + + + + + 1532.4000244140625 + + + + 2.0 + 101 + + + + + 1532.4000244140625 + + + + 2.0 + 101 + + + + + 1532.5999755859375 + + + + 2.0 + 103 + + + + + 1532.4000244140625 + + + + 2.0 + 106 + + + + + 1532.4000244140625 + + + + 2.0 + 106 + + + + + 1532.800048828125 + + + + 2.0 + 109 + + + + + 1532.800048828125 + + + + 2.0 + 109 + + + + + 1533.199951171875 + + + + 2.0 + 110 + + + + + 1533.4000244140625 + + + + 2.0 + 111 + + + + + 1534.4000244140625 + + + + 2.0 + 112 + + + + + 1535.4000244140625 + + + + 2.0 + 113 + + + + + 1535.5999755859375 + + + + 2.0 + 113 + + + + + 1535.800048828125 + + + + 2.0 + 113 + + + + + 1536 + + + + 2.0 + 114 + + + + + 1536.5999755859375 + + + + 2.0 + 114 + + + + + 1537 + + + + 2.0 + 115 + + + + + 1537.800048828125 + + + + 2.0 + 116 + + + + + 1538 + + + + 2.0 + 117 + + + + + 1538.199951171875 + + + + 1.0 + 117 + + + + + 1539 + + + + 1.0 + 117 + + + + + 1539.4000244140625 + + + + 1.0 + 116 + + + + + 1540 + + + + 1.0 + 117 + + + + + 1540.800048828125 + + + + 1.0 + 117 + + + + + 1541.4000244140625 + + + + 1.0 + 118 + + + + + 1541.800048828125 + + + + 1.0 + 119 + + + + + 1542 + + + + 1.0 + 119 + + + + + 1542.5999755859375 + + + + 1.0 + 120 + + + + + 1542.800048828125 + + + + 1.0 + 120 + + + + + 1543 + + + + 1.0 + 120 + + + + + 1543.800048828125 + + + + 1.0 + 120 + + + + + 1544 + + + + 1.0 + 119 + + + + + 1544.199951171875 + + + + 1.0 + 119 + + + + + 1544.5999755859375 + + + + 1.0 + 119 + + + + + 1544.800048828125 + + + + 1.0 + 118 + + + + + 1545.199951171875 + + + + 1.0 + 118 + + + + + 1545.800048828125 + + + + 1.0 + 119 + + + + + 1546.4000244140625 + + + + 1.0 + 119 + + + + + 1547 + + + + 1.0 + 120 + + + + + 1547.4000244140625 + + + + 1.0 + 121 + + + + + 1547.4000244140625 + + + + 1.0 + 121 + + + + + 1547.800048828125 + + + + 1.0 + 121 + + + + + 1547.800048828125 + + + + 1.0 + 120 + + + + + 1548.199951171875 + + + + 1.0 + 119 + + + + + 1548.199951171875 + + + + 1.0 + 116 + + + + + 1548.199951171875 + + + + 1.0 + 116 + + + + + 1548.199951171875 + + + + 1.0 + 113 + + + + + 1548.4000244140625 + + + + 1.0 + 112 + + + + + 1548.800048828125 + + + + 1.0 + 110 + + + + + 1549.199951171875 + + + + 0.0 + 111 + + + + + 1549.4000244140625 + + + + 0.0 + 111 + + + + + 1550 + + + + 0.0 + 111 + + + + + 1550.4000244140625 + + + + 0.0 + 110 + + + + + 1550.5999755859375 + + + + 0.0 + 108 + + + + + 1550.800048828125 + + + + 0.0 + 104 + + + + + 1550.800048828125 + + + + 0.0 + 103 + + + + + + diff --git a/testo.d/gpx.test b/testo.d/gpx.test index bf7739aab..80a356086 100644 --- a/testo.d/gpx.test +++ b/testo.d/gpx.test @@ -13,7 +13,7 @@ rm -f ${TMPDIR}/tpx-sample.gpx gpsbabel -i gpx -f ${REFERENCE}/track/gpx_garmin_extensions.gpx -o gpx,garminextensions -F ${TMPDIR}/tpx-sample.gpx compare ${REFERENCE}/track/gpx_garmin_extensions.gpx ${TMPDIR}/tpx-sample.gpx -rm -f ${TMPDIR}/basecampe~gpx.gpx +rm -f ${TMPDIR}/basecamp~gpx.gpx gpsbabel -i gpx -f ${REFERENCE}/basecamp.gpx -o gpx -F ${TMPDIR}/basecamp~gpx.gpx compare ${REFERENCE}/basecamp~gpx.gpx ${TMPDIR}/basecamp~gpx.gpx @@ -57,3 +57,7 @@ compare ${REFERENCE}/metadata~gpx.gpx ${TMPDIR}/metadata.gpx # output ilinks if gpx garamextensions specified gpsbabel -i gdb,dropwpt -f ${REFERENCE}/gdb-sample-v3-ilinks.gdb -o gpx,garminextensions -F ${TMPDIR}/gdb-sample-v3-ilinks.gpx compare ${REFERENCE}/gdb-sample-v3-ilinks.gpx ${TMPDIR}/gdb-sample-v3-ilinks.gpx + +# use declared namespace prefixes in gpx reader +gpsbabel -t -i gpx -f ${REFERENCE}/track/garminconnect.gpx -o unicsv,utc=0 -F ${TMPDIR}/garminconnect.csv +compare ${REFERENCE}/track/garminconnect.csv ${TMPDIR}/garminconnect.csv -- 2.30.2